home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <ctype.h>
-
-
- typedef struct
- {
- char *name;
- double *vals;
- double hl_t;
- double lh_t;
- double tphl;
- double tplh;
- } Signal;
-
-
- struct
- {
- int nv;
- int np;
- Signal *sigs;
- } plot;
-
- typedef struct
- {
- double w, l;
- } TranSz;
-
-
- double midpoint;
-
- Signal *timev, *in1, *in2, *in3, *out1, *out2, *out3, *out4;
-
-
- main( argc, argv )
- int argc;
- char *argv[];
- {
- FILE *fi = stdin;
- TranSz p, n;
- double cap;
- int i;
-
- cap = p.w = p.l = n.w = n.l = -1;
- for( i = 1; i < argc; i++ )
- {
- if( argv[i][0] == '-' )
- {
- switch( argv[i][1] )
- {
- case 'c' :
- i++;
- if( i >= argc ) usage( "missing argument :" );
- if( sscanf( argv[i], "%lf", &cap ) != 1 || cap <= 0 )
- usage( "bad argument for 'c': " );
- cap *= 1E-15; /* convert to ff */
- break;
- case 'n' :
- i++;
- if( i >= argc ) usage( "missing argument :" );
- if( sscanf( argv[i], "%lf,%lf", &n.w, &n.l ) != 2 ||
- n.w <= 0 || n.l <= 0 )
- usage( "bad argument for 'n': " );
- break;
- case 'p' :
- i++;
- if( i >= argc ) usage( "missing argument :" );
- if( sscanf( argv[i], "%lf,%lf", &p.w, &p.l ) != 2 ||
- p.w <= 0 || p.l <= 0 )
- usage( "bad argument for 'p': " );
- break;
- default :
- usage( "unknown switch :" );
- }
- }
- else
- {
- if( (fi = fopen( argv[i], "r" )) == NULL )
- usage( "can not open input file :" );
- }
- }
-
- if( cap <= 0 || n.l <= 0 || n.w <= 0 || p.l <= 0 || p.w <= 0 )
- usage( "i am missing parameters:" );
-
- if( read_header( fi ) == 0 )
- exit( 1 );
- if( read_variables( fi ) == 0 )
- exit( 1 );
- if( read_values( fi ) == 0 )
- exit( 1 );
- if( find_delays() == 0 )
- exit( 1 );
-
- PrintResistEntries( cap, &n, &p );
- exit( 0 );
- }
-
-
- usage( s )
- char *s;
- {
- fprintf( stderr, "%s\n", s );
- fprintf( stderr, "usage: findr -c <cap> -nfet <w,l> -pfet <w,l> [rawfile]\n" );
- fprintf( stderr, "\tcap -> loading capacitance (in fF)\n" );
- fprintf( stderr, "\tw,l -> width, length of fet (in um)\n" );
- fprintf( stderr, "\trawfile -> spice rawfile (ascii)\n" );
- exit( 1 );
- }
-
-
- #define eqsubstr( VS, FS ) ( strncmp( (VS), FS, sizeof( FS ) -1 ) == 0 )
-
- int read_header( f )
- FILE *f;
- {
- char line[512];
- int plotname = 0;
- char *s;
-
- while( fgets( line, 512, f ) )
- {
- if( eqsubstr( line, "Title:" ) )
- ;
- else if( eqsubstr( line, "Date:" ) )
- ;
- else if( eqsubstr( line, "Plotname:" ) )
- plotname = 1;
- else if( eqsubstr( line, "Flags:" ) )
- ;
- else if( eqsubstr( line, "Command:" ) )
- ;
- else if( eqsubstr( line, "No. Variables:" ) )
- {
- if( plotname == 0 )
- {
- fprintf( stderr, "missing Plotname entry\n" );
- return( 0 );
- }
- for( s = line; *s != ':'; s++ );
- s++;
- if( sscanf( s, "%d", &plot.nv ) != 1 || plot.nv <= 0 )
- {
- fprintf( stderr, "bad line: %s", line );
- return( 0 );
- }
- }
- else if( eqsubstr( line, "No. Points:" ) )
- {
- if( plotname == 0 )
- {
- fprintf( stderr, "missing Plotname entry\n" );
- return( 0 );
- }
- for( s = line; *s != ':'; s++ );
- s++;
- if( sscanf( s, "%d", &plot.np ) != 1 || plot.np <= 0 )
- {
- fprintf( stderr, "bad line: %s", line );
- return( 0 );
- }
- }
- else if( eqsubstr( line, "Variables:" ) )
- {
- if( plotname == 0 || plot.np == 0 | plot.nv == 0 )
- {
- fprintf( stderr, "missing entries:%s%s%s\n",
- (plotname) ? "" : " 'Plotname'",
- (plot.nv) ? "" : " 'No. Variables'",
- (plot.np) ? "" : " 'No. Points'" );
- }
- return( 1 );
- }
- else
- {
- fprintf( stderr, "Unrecognized line: %s", line );
- return( 0 );
- }
- }
- fprintf( stderr, "premature EOF\n" );
- return( 0 );
- }
-
-
-
- int read_variables( f )
- FILE *f;
- {
- char line[200], name[100], type[100];
- int i;
- int ix;
- double *v;
- char *s, *p;
-
- plot.sigs = (Signal *) calloc( plot.nv, sizeof( Signal ) );
- if( plot.sigs == NULL )
- {
- fprintf( stderr, "no memory\n" );
- return( 0 );
- }
-
- for( i = 0; i < plot.nv; i++ )
- {
- if( fgets( line, 200, f ) == NULL )
- {
- fprintf( stderr, "premature EOF\n" );
- return( 0 );
- }
- if( sscanf( line, "%d %s %s", &ix, name, type ) != 3 )
- {
- fprintf( stderr, "bad 'variable' line: %s", line );
- return( 0 );
- }
- s = (char *) malloc( strlen( name ) + 1 );
- v = (double *) calloc( plot.np, sizeof( double ) );
- if( v == NULL || s == NULL )
- {
- fprintf( stderr, "no memory\n" );
- return( 0 );
- }
- plot.sigs[i].vals = v;
- plot.sigs[i].name = s;
- for( p = name; *p != '\0'; p++, s++ )
- *s = ( isupper( *p ) ) ? tolower( *p ) : *p;
- *s = '\0';
- }
-
- if( fgets( line, 100, f ) == NULL )
- {
- fprintf( stderr, "premature EOF\n" );
- return( 0 );
- }
- if( eqsubstr( line, "Values:" ) )
- return( 1 );
-
- fprintf( stderr, "No 'Values' line\n" );
- return( 0 );
- }
-
-
- int read_values( f )
- FILE *f;
- {
- char line[200];
- int n, i, n_p, z;
- double v;
-
- for( n = 0; n < plot.np; n++ )
- {
- if( fgets( line, 200, f ) == NULL )
- {
- fprintf( stderr, "premature EOF\n" );
- return( 0 );
- }
-
- if( sscanf( line, "%d%lf", &n_p, &v ) != 2 || n_p != n )
- {
- fprintf( stderr, "bad 'value' line: %s", line );
- return( 0 );
- }
-
- plot.sigs[0].vals[n] = v;
- for( i = 1; i < plot.nv; i++ )
- {
- if( fgets( line, 200, f ) == NULL )
- {
- fprintf( stderr, "premature EOF\n" );
- return( 0 );
- }
- if( sscanf( line, "%lf", &v ) != 1 )
- {
- fprintf( stderr, "bad 'value' line: %s", v, line );
- return( 0 );
- }
- plot.sigs[i].vals[n] = v;
- }
- }
- return( 1 );
- }
-
-
- Signal *find( name )
- char *name;
- {
- int i;
- Signal *sig;
-
- for( i = 0, sig = plot.sigs; i < plot.nv; i++, sig++ )
- {
- if( strcmp( name, sig->name ) == 0 )
- return( sig );
- }
- return( NULL );
- }
-
-
- double interp( y, v1, v2, t1, t2 )
- double y, v1, v2, t1, t2;
- {
- return( t2 + (y - v2) * (t2 - t1) / (v2 - v1) );
- }
-
-
- #define L_H 1
- #define H_L 2
- #define BOTH ( L_H | H_L )
-
- Signal *FindTransitions( name, which )
- char *name;
- int which;
- {
- Signal *sig;
- double *v, *t;
- int i;
-
- if( (sig = find( name )) == NULL )
- {
- fprintf( stderr, "signal '%s' missing\n" );
- return( NULL );
- }
- v = sig->vals;
- t = timev->vals;
-
- if( which & L_H )
- {
- for( i = 1; i < plot.np; i++ )
- {
- if( v[i-1] < midpoint && v[i] >= midpoint )
- goto foundlh;
- }
- fprintf( stderr, "signal '%s' has no l->h transition\n", name );
- return( NULL );
-
- foundlh :
- sig->lh_t = interp( midpoint, v[i-1], v[i], t[i-1], t[i] );
- }
-
- if( which & H_L )
- {
- for( i = 1; i < plot.np; i++ )
- {
- if( v[i-1] > midpoint && v[i] <= midpoint )
- goto foundhl;
- }
- fprintf( stderr, "signal '%s' has no h->l transition\n", name );
- return( NULL );
-
- foundhl :
- sig->hl_t = interp( midpoint, v[i-1], v[i], t[i-1], t[i] );
- }
-
- return( sig );
- }
-
-
- int find_delays()
- {
- Signal *vdd;
-
- if( (timev = find( "time" )) == NULL )
- {
- fprintf( stderr, "variable 'time' missing\n" );
- return( 0 );
- }
- if( (vdd = find( "vdd" )) == NULL )
- {
- fprintf( stderr, "variable 'vdd' missing\n" );
- return( 0 );
- }
- midpoint = vdd->vals[0] / 2.0;
-
- if( (in1 = FindTransitions( "in1", BOTH )) == NULL ) return( 0 );
- if( (in2 = FindTransitions( "in2", L_H )) == NULL ) return( 0 );
- if( (in3 = FindTransitions( "in3", H_L )) == NULL ) return( 0 );
- if( (out1 = FindTransitions( "out1", BOTH )) == NULL ) return( 0 );
- if( (out2 = FindTransitions( "out2", BOTH )) == NULL ) return( 0 );
- if( (out3 = FindTransitions( "out3", L_H )) == NULL ) return( 0 );
- if( (out4 = FindTransitions( "out4", H_L )) == NULL ) return( 0 );
-
- out1->tphl = out1->hl_t - in1->lh_t;
- out1->tplh = out1->lh_t - in1->hl_t;
-
- out2->tphl = out2->hl_t - out1->lh_t;
- out2->tplh = out2->lh_t - out1->hl_t;
-
- out3->tplh = out3->lh_t - in2->lh_t;
- out4->tphl = out4->hl_t - in3->hl_t;
-
- return( 1 );
- }
-
-
- #define SQ( A ) ( (A) * (A) )
-
- PrintResistEntries( cap, ns, ps )
- double cap;
- TranSz *ns, *ps;
- {
- double dyn_h, dyn_l, stat;
-
- dyn_h = out3->tplh / cap;
- dyn_l = out1->tphl / cap;
- stat = ( SQ( out2->tphl ) - SQ( out1->tphl ) ) / (out1->tplh * cap );
- PrintR( "n-channel", ns->w, ns->l, dyn_h, dyn_l, stat );
-
- printf( "\n" );
-
- dyn_h = out1->tplh / cap;
- dyn_l = out4->tphl / cap;
- stat = ( SQ( out2->tplh ) - SQ( out1->tplh ) ) / (out1->tphl * cap );
- PrintR( "p-channel", ps->w, ps->l, dyn_h, dyn_l, stat );
- }
-
-
- #define round( A ) (int) ( (A) + 0.5 )
-
-
- PrintR( ttype, w, l, rh, rl, rs )
- char *ttype;
- double w, l, rh, rl, rs;
- {
- static char *fmt = "resitance %s %s\t%.1f\t%.1f\t%d.0\n";
-
- printf( fmt, ttype, "dynamic-high", w, l, round( rh ) );
- printf( fmt, ttype, "dynamic-low\t", w, l, round( rl ) );
- printf( fmt, ttype, "static\t", w, l, round( rs ) );
- }
-